Xradar Logo Xradar Logo

An Introduction to Radar Data in Pangeo Using Xradar + Py-ART


Overview

If you have an introductory paragraph, lead with it here! Keep it short and tied to your material, then be sure to continue into the required list of topics below,

  1. Introduction to Py-ART 1.0

  2. Introduction to xradar

  3. The power of common data models

  4. Visualization fun

Prerequisites

Concepts

Importance

Notes

Introduction to Xarray

Necessary

Familiarity with data model

Py-ART Basics

Necessary

Familiarity with data model

Understanding of NetCDF

Helpful

Familiarity with metadata structure

Comet/MetEd Radar Fundamentals

Helpful

Familiarity with radar science

  • Time to learn: estimate in minutes. For a rough idea, use 5 mins per subsection, 10 if longer; add these up for a total. Safer to round up and overestimate.

  • System requirements:

    • Populate with any system, version, or non-Python software requirements if necessary

    • Otherwise use the concepts table above and the Imports section below to describe required packages as necessary

    • If no extra requirements, remove the System requirements point altogether


Imports

Begin your body of content with another --- divider before continuing into this section, then remove this body text and populate the following code cell with all necessary Python imports up-front:

import pyart
from open_radar_data import DATASETS
import xradar as xd
import xarray as xr
import hvplot.xarray
import holoviews as hv
import cartopy.crs as ccrs
import cmweather
import wradlib

hv.extension("bokeh")
## You are using the Python ARM Radar Toolkit (Py-ART), an open source
## library for working with weather radar data. Py-ART is partly
## supported by the U.S. Department of Energy as part of the Atmospheric
## Radiation Measurement (ARM) Climate Research Facility, an Office of
## Science user facility.
##
## If you use this software to prepare a publication, please cite:
##
##     JJ Helmus and SM Collis, JORS 2016, doi: 10.5334/jors.119

An Introduction to Py-ART 1.0

This is where you begin your first section of material, loosely tied to your objectives stated up front. Tie together your notebook as a narrative, with interspersed Markdown text, images, and more as necessary,

Read in Data, Load into the Radar Object

Here, we use a sample file from a radar used for a field campaign in the Colorado Rockies!

file = DATASETS.fetch("gucxprecipradarcmacppiS2.c1.20220314.021559.nc")
file
Downloading file 'gucxprecipradarcmacppiS2.c1.20220314.021559.nc' from 'https://github.com/openradar/open-radar-data/raw/main/data/gucxprecipradarcmacppiS2.c1.20220314.021559.nc' to '/home/runner/.cache/open-radar-data'.
'/home/runner/.cache/open-radar-data/gucxprecipradarcmacppiS2.c1.20220314.021559.nc'
radar = pyart.io.read(file)
radar
/home/runner/miniconda3/envs/open-radar-pangeo-showcase-2024-dev/lib/python3.10/site-packages/pyart/io/cfradial.py:412: UserWarning: WARNING: valid_min not used since it
cannot be safely cast to variable data type
  data = self.ncvar[:]
/home/runner/miniconda3/envs/open-radar-pangeo-showcase-2024-dev/lib/python3.10/site-packages/pyart/io/cfradial.py:412: UserWarning: WARNING: valid_max not used since it
cannot be safely cast to variable data type
  data = self.ncvar[:]
<pyart.core.radar.Radar at 0x7f1d57106dd0>

Create a Quick Plot

One of Py-ART’s key benefits is the easy plotting classes users can utilize with their radar object!

More plotting examples in the gallery

display = pyart.graph.RadarDisplay(radar)
display.plot("corrected_reflectivity")
../_images/f98fb8e646e0732695c3de3abd9e766d47da63334e440a396ca5d70efc56e4b6.png

Ivestigate the radar object

But… how did we know that field was in there? What the heck is this object?

dir(radar)
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getstate__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__setstate__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_check_sweep_in_range',
 '_dic_info',
 'add_field',
 'add_field_like',
 'add_filter',
 'altitude',
 'altitude_agl',
 'antenna_transition',
 'azimuth',
 'check_field_exists',
 'drift',
 'elevation',
 'extract_sweeps',
 'fields',
 'fixed_angle',
 'gate_altitude',
 'gate_latitude',
 'gate_longitude',
 'gate_x',
 'gate_y',
 'gate_z',
 'georefs_applied',
 'get_azimuth',
 'get_elevation',
 'get_end',
 'get_field',
 'get_gate_area',
 'get_gate_lat_lon_alt',
 'get_gate_x_y_z',
 'get_nyquist_vel',
 'get_slice',
 'get_start',
 'get_start_end',
 'heading',
 'info',
 'init_gate_altitude',
 'init_gate_longitude_latitude',
 'init_gate_x_y_z',
 'init_rays_per_sweep',
 'instrument_parameters',
 'iter_azimuth',
 'iter_elevation',
 'iter_end',
 'iter_field',
 'iter_slice',
 'iter_start',
 'iter_start_end',
 'latitude',
 'longitude',
 'metadata',
 'ngates',
 'nrays',
 'nsweeps',
 'pitch',
 'projection',
 'radar_calibration',
 'range',
 'ray_angle_res',
 'rays_are_indexed',
 'rays_per_sweep',
 'roll',
 'rotation',
 'scan_rate',
 'scan_type',
 'sweep_end_ray_index',
 'sweep_mode',
 'sweep_number',
 'sweep_start_ray_index',
 'target_scan_rate',
 'tilt',
 'time']

Where’s the data???

It’s all in the fields!

A dictionary of dictionaries… ahhh pre-xarray days…

radar.fields
{'DBZ': {'_FillValue': -32768.0,
  'long_name': 'Equaivalent_radar_reflectiivity_factor',
  'units': 'dBZ',
  'standard_name': 'equivalent_reflectivity_factor',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[ 5.3499999 ,  9.38999939,  9.60999966, ...,  7.50999975,
            3.56999993,  7.52999973],
          [ 6.85999966,  8.85999966,  8.43999958, ...,  7.50999975,
            4.9000001 ,  7.52999973],
          [ 7.26999998,  8.97999954,  4.21999979, ...,  7.50999975,
            4.9000001 ,  7.52999973],
          ...,
          [10.11999989,  8.34999943,  8.13999939, ...,  7.50999975,
            7.51999998,  7.52999973],
          [ 8.94999981,  6.36999989,  6.96000004, ...,  7.50999975,
            7.51999998,  7.52999973],
          [ 7.61999989,  6.30999994,  5.29999971, ...,  7.50999975,
            7.51999998,  7.52999973]],
    mask=False,
    fill_value=1e+20)},
 'VEL': {'_FillValue': -32768.0,
  'long_name': 'Radial Doppler Velocity, Positive for Motion Away from Instrument',
  'units': 'm/s',
  'standard_name': 'radial_velocity_of_scatterers_away_from_instruments',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[  1.76999998,   2.76999998,   3.74000001, ...,  -6.37999964,
            -1.14999998,  -3.05999994],
          [  1.96999991,   2.54999995,   3.7099998 , ...,  -5.19999981,
            -3.05999994,  -5.31999969],
          [  1.82999992,   2.78999996,   3.68999982, ...,  -8.92999935,
            -3.88999987,  13.27999973],
          ...,
          [  1.5999999 ,   1.41999996,   2.08999991, ...,   3.52999997,
            27.40999985,  23.70999908],
          [  1.56999993,   1.14999998,   2.        , ...,   3.80999994,
            -3.24000001,  23.        ],
          [  1.5999999 ,   1.30999994,   2.11999989, ...,   3.27999997,
           -24.88999939,   0.38999999]],
    mask=False,
    fill_value=1e+20)},
 'WIDTH': {'_FillValue': -32768.0,
  'long_name': 'Spectral Width',
  'units': 'm/s',
  'standard_name': 'doppler_spectrum_width',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[1.69999993, 2.46000004, 1.17999995, ..., 3.30999994, 3.02999997,
           2.12999988],
          [1.75      , 2.26999998, 0.98999995, ..., 2.95000005, 3.63999987,
           2.50999999],
          [1.71999991, 2.19000006, 1.41999996, ..., 2.32999992, 3.77999997,
           2.71000004],
          ...,
          [1.01999998, 1.01999998, 0.63      , ..., 2.96000004, 3.01999998,
           2.20000005],
          [1.09000003, 1.18999994, 0.68000001, ..., 2.96000004, 2.78999996,
           1.89999998],
          [1.33999991, 1.25      , 0.88999999, ..., 2.25999999, 2.63999987,
           2.91999984]],
    mask=False,
    fill_value=1e+20)},
 'ZDR': {'_FillValue': -32768.0,
  'long_name': 'Differential Reflectivity',
  'units': 'dB',
  'standard_name': 'log_differential_reflectivity_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[1.85000007, 3.53999998, 2.97      , ..., 1.82999997, 3.60000001,
           2.13000004],
          [2.27000003, 3.80999999, 2.67      , ..., 2.32000004, 2.32000004,
           2.56000002],
          [2.71      , 3.84999995, 3.19999999, ..., 2.67      , 2.00000005,
           2.54000001],
          ...,
          [3.09      , 3.94999998, 3.02      , ..., 3.03      , 3.55999999,
           2.54000001],
          [3.49999999, 4.03999995, 2.98      , ..., 3.31999998, 2.36999999,
           2.34000002],
          [3.76999997, 3.57999997, 3.62999998, ..., 3.66000001, 2.15000002,
           2.68      ]],
    mask=False,
    fill_value=1e+20)},
 'PHIDP': {'_FillValue': -32768.0,
  'long_name': 'Differential Phase',
  'units': 'degree',
  'standard_name': 'differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[ 89.95999908,  96.76999664,  98.90000153, ..., 280.95999908,
           299.26000214, 293.23000336],
          [ 94.04999542,  98.37999725,  99.62999725, ..., 282.26000214,
           350.5       , 248.79000092],
          [ 93.45999908, 100.20999908,  97.38999939, ..., 321.63999939,
           329.46000099, 303.17000198],
          ...,
          [ 98.29999542, 104.27999878, 102.98999786, ...,  59.59000015,
           334.52000046, 333.11000061],
          [ 98.63999939, 104.90999603, 101.22000122, ...,  27.56999969,
           327.94000244, 315.49000168],
          [ 99.16999817, 105.11999512, 106.        , ..., 319.04999924,
           349.60000038, 338.90999985]],
    mask=False,
    fill_value=1e+20)},
 'RHOHV': {'_FillValue': -32768.0,
  'long_name': 'Cross-Polar Correlation Ratio',
  'units': '1',
  'standard_name': 'cross_correlation_ratio_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.97400004, 0.99200004, 0.99300003, ..., 0.70700002, 0.33100003,
           0.46600002],
          [0.96700007, 0.98200005, 0.98300004, ..., 0.81400001, 0.37300003,
           0.45500001],
          [0.95600003, 0.97800004, 0.96200007, ..., 0.53800005, 0.62200004,
           0.44500002],
          ...,
          [0.98000002, 0.98100007, 0.98200005, ..., 0.33600003, 0.38500002,
           0.71100003],
          [0.97000003, 0.97700006, 0.98300004, ..., 0.38200003, 0.45300001,
           0.56700003],
          [0.96000004, 0.98000002, 0.97500002, ..., 0.42800003, 0.54500002,
           0.34800002]],
    mask=False,
    fill_value=1e+20)},
 'NCP': {'_FillValue': -32768.0,
  'long_name': 'Normalized Coherent Power, also known as SQI',
  'units': '1',
  'standard_name': 'normalized_coherent_power',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.90999997, 0.83999997, 0.91999996, ..., 0.16      , 0.14      ,
           0.17      ],
          [0.90999997, 0.85999995, 0.94999999, ..., 0.11      , 0.14      ,
           0.22      ],
          [0.89999998, 0.87      , 0.93000001, ..., 0.12      , 0.14      ,
           0.22      ],
          ...,
          [0.95999998, 0.95999998, 0.97999996, ..., 0.11      , 0.17999999,
           0.13      ],
          [0.95999998, 0.94      , 0.96999997, ..., 0.09999999, 0.14999999,
           0.14999999],
          [0.94999999, 0.93000001, 0.95999998, ..., 0.09999999, 0.11      ,
           0.13      ]],
    mask=False,
    fill_value=1e+20)},
 'DBZhv': {'_FillValue': -32768.0,
  'long_name': 'Equivalent Reflectivity Factor HV',
  'units': 'dBZ',
  'standard_name': 'equivalent_reflectivity_factor_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[ 6.39999962,  9.17000008,  9.55000019, ..., -0.76999998,
           -1.81999993, -1.31999993],
          [ 7.75999975,  7.86999989,  7.90999985, ..., -0.53999996,
           -1.65999997, -1.52999997],
          [ 7.46999979,  7.94999981,  2.42999983, ..., -0.22      ,
            0.25999999, -1.25999999],
          ...,
          [11.13999939,  9.40999985,  8.71000004, ..., -1.32999992,
           -1.16999996, -2.3499999 ],
          [ 9.28999996,  5.44999981,  7.51999998, ..., -0.57999998,
           -0.44999999, -6.        ],
          [ 7.46000004,  4.26999998,  3.07999992, ..., -1.63      ,
           -0.82999998, -3.02999997]],
    mask=False,
    fill_value=1e+20)},
 'cbb_flag': {'long_name': 'Cumulative Beam Block Fraction Flag',
  'units': '1',
  'coordinates': 'elevation azimuth range',
  'comment': 'Cumulative beam block flag due to terrain.',
  'data': masked_array(
    data=[[0., 0., 0., ..., 1., 1., 1.],
          [0., 0., 0., ..., 1., 1., 1.],
          [0., 0., 0., ..., 1., 1., 1.],
          ...,
          [0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.]],
    mask=False,
    fill_value=1e+20)},
 'sounding_temperature': {'long_name': 'Interpolated profile',
  'units': 'degC',
  'standard_name': 'interpolated_profile',
  'data': masked_array(
    data=[[ -2.3462055,  -2.4152544,  -2.4588518, ..., -34.118    ,
           -34.18     , -34.232002 ],
          [ -2.3462055,  -2.4152544,  -2.4588518, ..., -34.15     ,
           -34.208    , -34.258    ],
          [ -2.3462055,  -2.4152544,  -2.468688 , ..., -34.190002 ,
           -34.24     , -34.278    ],
          ...,
          [ -2.3565507,  -2.4152544,  -2.468688 , ..., -34.381226 ,
           -34.42917  , -34.471428 ],
          [ -2.3565507,  -2.4152544,  -2.468688 , ..., -34.381226 ,
           -34.42917  , -34.471428 ],
          [ -2.3565507,  -2.4152544,  -2.468688 , ..., -34.381226 ,
           -34.42917  , -34.471428 ]],
    mask=False,
    fill_value=1e+20,
    dtype=float32)},
 'height': {'long_name': 'Height of radar beam',
  'units': 'm',
  'standard_name': 'height',
  'data': masked_array(
    data=[[3180.2, 3187.2, 3192.2, ..., 7398.2, 7405.2, 7411.2],
          [3180.2, 3187.2, 3192.2, ..., 7402.2, 7408.2, 7415.2],
          [3180.2, 3187.2, 3193.2, ..., 7406.2, 7412.2, 7418.2],
          ...,
          [3181.2, 3187.2, 3193.2, ..., 7432.2, 7439.2, 7445.2],
          [3181.2, 3187.2, 3193.2, ..., 7432.2, 7439.2, 7445.2],
          [3181.2, 3187.2, 3193.2, ..., 7432.2, 7439.2, 7445.2]],
    mask=False,
    fill_value=1e+20,
    dtype=float32)},
 'signal_to_noise_ratio': {'_FillValue': -32768.0,
  'long_name': 'Signal to Noise Ratio',
  'units': 'dB',
  'standard_name': 'signal_to_noise_ratio',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[40.18000031, 42.66999817, 41.56999969, ...,  0.        ,
           -3.94999981,  0.        ],
          [41.68999863, 42.13999939, 40.39999771, ...,  0.        ,
           -2.61999989,  0.        ],
          [42.09000015, 42.25      , 36.18000031, ...,  0.        ,
           -2.61999989,  0.        ],
          ...,
          [44.95000076, 41.62999725, 40.11000061, ...,  0.        ,
            0.        ,  0.        ],
          [43.77999878, 39.63999939, 38.91999817, ...,  0.        ,
            0.        ,  0.        ],
          [42.45000076, 39.59000015, 37.25999832, ...,  0.        ,
            0.        ,  0.        ]],
    mask=False,
    fill_value=1e+20)},
 'velocity_texture': {'long_name': 'Mean dopper velocity',
  'units': 'm/s',
  'standard_name': 'radial_velocity_of_scatterers_away_from_instrument',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.95980847, 0.88251601, 0.83554892, ..., 6.45901397, 5.62455843,
           5.00792857],
          [0.83920148, 0.83554892, 0.79410012, ..., 6.41084159, 5.62455843,
           5.00792857],
          [0.79410012, 0.73037925, 0.73037925, ..., 6.30690828, 6.02653167,
           5.34782884],
          ...,
          [0.29748918, 0.30600555, 0.45446138, ..., 5.26087378, 5.38360144,
           5.38360144],
          [0.29443759, 0.29443759, 0.45446138, ..., 4.9112846 , 5.22778187,
           5.52338061],
          [0.28717293, 0.28717293, 0.46040409, ..., 4.52095116, 5.10617287,
           5.22778187]],
    mask=False,
    fill_value=1e+20)},
 'gate_id': {'long_name': 'Classification of dominant scatterer',
  'units': '1',
  'notes': '0:multi_trip,1:rain,2:snow,3:no_scatter,4:melting,5:clutter,6:terrain_blockage',
  'valid_max': '6',
  'valid_min': '0',
  'flag_values': '0, 1, 2, 3, 4, 5, 6',
  'flag_meanings': 'multi_trip rain snow no_scatter melting clutter terrain_blockage',
  'data': masked_array(
    data=[[2, 2, 2, ..., 6, 6, 6],
          [2, 2, 2, ..., 6, 6, 6],
          [2, 2, 2, ..., 6, 6, 6],
          ...,
          [2, 2, 2, ..., 3, 3, 3],
          [2, 2, 2, ..., 3, 3, 3],
          [2, 2, 2, ..., 3, 3, 3]],
    mask=False,
    fill_value=999999)},
 'simulated_velocity': {'long_name': 'Simulated mean doppler velocity',
  'units': 'm/s',
  'standard_name': 'radial_velocity_of_scatterers_away_from_instrument',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[-4.04460068, -3.96199123, -3.94839799, ..., 12.92917905,
           12.92917905, 12.96911246],
          [-4.04456044, -3.96195182, -3.94835871, ..., 12.92905043,
           12.93903185, 12.97896974],
          [-4.03869838, -3.95620948, -3.92755288, ..., 13.0073836 ,
           13.05760291, 13.05760536],
          ...,
          [-4.02602798, -3.9593496 , -3.93067025, ..., 12.95954531,
           12.95954531, 12.95954531],
          [-4.02602798, -3.9593496 , -3.93067025, ..., 12.95954531,
           12.95954531, 12.95954531],
          [-4.02602798, -3.9593496 , -3.93067025, ..., 12.95954531,
           12.95954531, 12.95954531]],
    mask=False,
    fill_value=1e+20)},
 'corrected_velocity': {'_FillValue': -32768.0,
  'long_name': 'Corrected mean doppler velocity',
  'units': 'm/s',
  'standard_name': 'corrected_radial_velocity_of_scatterers_away_from_instrument',
  'coordinates': 'elevation azimuth range',
  'valid_min': '-79.5',
  'valid_max': '79.5',
  'data': masked_array(
    data=[[1.7699999809265137, 2.7699999809265137, 3.740000009536743, ...,
           --, --, --],
          [1.96999990940094, 2.549999952316284, 3.7099997997283936, ...,
           --, --, --],
          [1.8299999237060547, 2.7899999618530273, 3.68999981880188, ...,
           --, --, --],
          ...,
          [1.5999999046325684, 1.4199999570846558, 2.0899999141693115, ...,
           --, --, --],
          [1.5699999332427979, 1.149999976158142, 2.0, ..., --, --, --],
          [1.5999999046325684, 1.309999942779541, 2.119999885559082, ...,
           --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=-32768.0)},
 'unfolded_differential_phase': {'_FillValue': -32768.0,
  'long_name': 'Unfolded differential propagation phase shift',
  'units': 'degree',
  'standard_name': 'differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.],
          ...,
          [0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.],
          [0., 0., 0., ..., 0., 0., 0.]],
    mask=False,
    fill_value=1e+20)},
 'corrected_differential_phase': {'_FillValue': -32768.0,
  'long_name': 'Corrected differential propagation phase shift',
  'units': 'degree',
  'standard_name': 'differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0.0',
  'valid_max': '400.0',
  'data': masked_array(
    data=[[0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01],
          [0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01],
          [0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01],
          ...,
          [0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01],
          [0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01],
          [0.01, 0.01, 0.01, ..., 0.01, 0.01, 0.01]],
    mask=False,
    fill_value=1e+20)},
 'filtered_corrected_differential_phase': {'_FillValue': -32768.0,
  'long_name': 'Filtered Corrected Differential Phase',
  'units': 'degree',
  'standard_name': 'differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0.0',
  'valid_max': '400.0',
  'data': masked_array(
    data=[[-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -6.05577610e-19, -6.05577610e-19,  1.00000000e-02],
          [-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -5.55749303e-19, -5.55749303e-19,  1.00000000e-02],
          [-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -4.88462899e-19, -4.88462899e-19,  1.00000000e-02],
          ...,
          [-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -5.34654088e-19, -5.34654088e-19,  1.00000000e-02],
          [-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -6.41221224e-19, -6.41221224e-19,  1.00000000e-02],
          [-4.36452341e-21, -1.30935702e-20, -2.61871405e-20, ...,
           -6.41221224e-19, -6.41221224e-19,  1.00000000e-02]],
    mask=False,
    fill_value=1e+20)},
 'corrected_specific_diff_phase': {'_FillValue': -9999.0,
  'long_name': 'Specific differential phase (KDP)',
  'units': 'degrees/km',
  'standard_name': 'specific_differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          ...,
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00]],
    mask=False,
    fill_value=1e+20)},
 'filtered_corrected_specific_diff_phase': {'_FillValue': -9999.0,
  'long_name': 'Filtered Corrected Specific differential phase (KDP)',
  'units': 'degrees/km',
  'standard_name': 'specific_differential_phase_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          ...,
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
          [-2.43197823e-20, -7.29593470e-20, -1.21598912e-19, ...,
            0.00000000e+00,  0.00000000e+00,  0.00000000e+00]],
    mask=False,
    fill_value=1e+20)},
 'corrected_differential_reflectivity': {'_FillValue': 1e+20,
  'long_name': 'Corrected differential reflectivity',
  'units': 'dB',
  'standard_name': 'corrected_log_differential_reflectivity_hv',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[1.8500000715255736, 3.5399999797344206, 2.970000001788139, ...,
           --, --, --],
          [2.2700000286102293, 3.8099999904632567, 2.6700000047683714, ...,
           --, --, --],
          [2.709999996423721, 3.849999952316284, 3.199999991059303, ...,
           --, --, --],
          ...,
          [3.08999999910593, 3.949999976158142, 3.020000000670552, ..., --,
           --, --],
          [3.499999988079071, 4.039999949932098, 2.9799999997019766, ...,
           --, --, --],
          [3.7699999690055845, 3.5799999713897703, 3.6299999833106993, ...,
           --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'corrected_reflectivity': {'_FillValue': 1e+20,
  'long_name': 'Corrected reflectivity',
  'units': 'dBZ',
  'standard_name': 'corrected_equivalent_reflectivity_factor',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[5.349999904632568, 9.389999389648438, 9.609999656677246, ...,
           --, --, --],
          [6.859999656677246, 8.859999656677246, 8.4399995803833, ..., --,
           --, --],
          [7.269999980926514, 8.979999542236328, 4.21999979019165, ..., --,
           --, --],
          ...,
          [10.119999885559082, 8.34999942779541, 8.139999389648438, ...,
           --, --, --],
          [8.949999809265137, 6.369999885559082, 6.960000038146973, ...,
           --, --, --],
          [7.619999885559082, 6.309999942779541, 5.299999713897705, ...,
           --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'height_over_iso0': {'long_name': 'Height of radar beam over freezing level',
  'units': 'm',
  'standard_name': 'height',
  'data': masked_array(
    data=[[nan, nan, nan, ..., nan, nan, nan],
          [nan, nan, nan, ..., nan, nan, nan],
          [nan, nan, nan, ..., nan, nan, nan],
          ...,
          [nan, nan, nan, ..., nan, nan, nan],
          [nan, nan, nan, ..., nan, nan, nan],
          [nan, nan, nan, ..., nan, nan, nan]],
    mask=False,
    fill_value=1e+20,
    dtype=float32)},
 'specific_attenuation': {'_FillValue': 1e+20,
  'long_name': 'Specific attenuation',
  'units': 'dB/km',
  'standard_name': 'specific_attenuation',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0.0',
  'valid_max': '1.0',
  'data': masked_array(
    data=[[0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          ...,
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'path_integrated_attenuation': {'_FillValue': 1e+20,
  'long_name': 'Path Integrated Attenuation',
  'units': 'dB',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          ...,
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'specific_differential_attenuation': {'_FillValue': 1e+20,
  'long_name': 'Specific Differential Attenuation',
  'units': 'dB/km',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          ...,
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'path_integrated_differential_attenuation': {'_FillValue': 1e+20,
  'long_name': 'Path Integrated Differential Attenuation',
  'units': 'dB',
  'coordinates': 'elevation azimuth range',
  'data': masked_array(
    data=[[0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          ...,
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'rain_rate_A': {'_FillValue': 1e+20,
  'long_name': 'Rainfall Rate from Specific Attenuation',
  'units': 'mm/hr',
  'standard_name': 'rainfall_rate',
  'coordinates': 'elevation azimuth range',
  'least_significant_digit': 1,
  'comment': 'Rain rate calculated from specific_attenuation, R=43.5*specific_attenuation**0.79, note R=0.0 where norm coherent power < 0.4 or rhohv < 0.8',
  'valid_min': '0.0',
  'valid_max': '400.0',
  'data': masked_array(
    data=[[0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          ...,
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --],
          [0.0, 0.0, 0.0, ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'snow_rate_ws2012': {'_FillValue': 1e+20,
  'long_name': 'Snowfall rate from Z using Wolf and Snider (2012)',
  'units': 'mm/h',
  'standard_name': 'snowfall_rate',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0',
  'valid_max': '500',
  'swe_ratio': '13.699',
  'A': '110',
  'B': '2',
  'data': masked_array(
    data=[[0.17652395640137936, 0.28106296725172597, 0.28827278262198935,
           ..., --, --, --],
          [0.2100407886358824, 0.2644256863269999, 0.25194377738869717,
           ..., --, --, --],
          [0.22019307501812282, 0.2681042105157746, 0.1549899888164853,
           ..., --, --, --],
          ...,
          [0.3057057811683439, 0.2493467022536862, 0.24339050225771308,
           ..., --, --, --],
          [0.267179816896248, 0.19851971895737944, 0.21247295567206081,
           ..., --, --, --],
          [0.22924699505759605, 0.19715312012338218, 0.1755107180920355,
           ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'snow_rate_ws88diw': {'_FillValue': 1e+20,
  'long_name': 'Snowfall rate from Z using WSR 88D High Plains',
  'units': 'mm/h',
  'standard_name': 'snowfall_rate',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0',
  'valid_max': '500',
  'swe_ratio': '13.699',
  'A': '40',
  'B': '2',
  'data': masked_array(
    data=[[0.2927318649462153, 0.46609020241896115, 0.47804632861441165,
           ..., --, --, --],
          [0.3483132432877832, 0.4385003932394344, 0.4178014889315676, ...,
           --, --, --],
          [0.36514890563484625, 0.44460053549764045, 0.2570218195828306,
           ..., --, --, --],
          ...,
          [0.5069556861889462, 0.4134947270439711, 0.4036174867624916, ...,
           --, --, --],
          [0.4430676021003563, 0.3292077106342157, 0.35234653603102045,
           ..., --, --, --],
          [0.3801631334612524, 0.3269414628485627, 0.29105159929856145,
           ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'snow_rate_m2009_1': {'_FillValue': 1e+20,
  'long_name': 'Snowfall rate from Z using Matrosov et al.(2009) Braham(1990) 1',
  'units': 'mm/h',
  'standard_name': 'snowfall_rate',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0',
  'valid_max': '500',
  'swe_ratio': '13.699',
  'A': '67',
  'B': '1.28',
  'data': masked_array(
    data=[[0.09802747200957339, 0.2027555554981298, 0.21094065176843244,
           ..., --, --, --],
          [0.1286223776774802, 0.18431748402559525, 0.17090470838886448,
           ..., --, --, --],
          [0.13846748651837235, 0.1883395483532741, 0.07999568175760745,
           ..., --, --, --],
          ...,
          [0.23120863590817595, 0.16816002594348523, 0.1619259720053442,
           ..., --, --, --],
          [0.18732588605183864, 0.11777016986310176, 0.130957104270401,
           ..., --, --, --],
          [0.14746588157528065, 0.116505869632889, 0.09714971660031632,
           ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)},
 'snow_rate_m2009_2': {'_FillValue': 1e+20,
  'long_name': 'Snowfall rate from Z using Matrosov et al.(2009) Braham(1990) 2',
  'units': 'mm/h',
  'standard_name': 'snowfall_rate',
  'coordinates': 'elevation azimuth range',
  'valid_min': '0',
  'valid_max': '500',
  'swe_ratio': '13.699',
  'A': '114',
  'B': '1.39',
  'data': masked_array(
    data=[[0.08037193357461173, 0.1569465818472422, 0.16277181979683336,
           ..., --, --, --],
          [0.10321373456165439, 0.14375480980848285, 0.13409313722293925,
           ..., --, --, --],
          [0.11046734559487273, 0.1466410189496867, 0.06665142582252989,
           ..., --, --, --],
          ...,
          [0.17712092960144296, 0.13210879171494475, 0.12759210547463656,
           ..., --, --, --],
          [0.14591408480746687, 0.09516685344560759, 0.10493775392442406,
           ..., --, --, --],
          [0.11706141455918391, 0.09422565554197429, 0.0797089853078306,
           ..., --, --, --]],
    mask=[[False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          ...,
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True],
          [False, False, False, ...,  True,  True,  True]],
    fill_value=1e+20)}}

Introduction to xradar

Re-writing the readers, coming to a community standard.

Reading data using xradar

We can read in a single elevation (ex. sweep_0)

first_sweep = xr.open_dataset(file, engine='cfradial1', group='sweep_0')
first_sweep
<xarray.Dataset> Size: 195MB
Dimensions:                                   (azimuth: 1159, range: 668)
Coordinates:
    time                                      (azimuth) datetime64[ns] 9kB ...
  * range                                     (range) float32 3kB 306.9 ... 4...
    elevation                                 (azimuth) float32 5kB ...
  * azimuth                                   (azimuth) float32 5kB 0.05238 ....
    latitude                                  float64 8B ...
    longitude                                 float64 8B ...
    altitude                                  float64 8B ...
Data variables: (12/37)
    DBZ                                       (azimuth, range) float64 6MB ...
    VEL                                       (azimuth, range) float64 6MB ...
    WIDTH                                     (azimuth, range) float64 6MB ...
    ZDR                                       (azimuth, range) float64 6MB ...
    PHIDP                                     (azimuth, range) float64 6MB ...
    RHOHV                                     (azimuth, range) float64 6MB ...
    ...                                        ...
    snow_rate_m2009_1                         (azimuth, range) float64 6MB ...
    snow_rate_m2009_2                         (azimuth, range) float64 6MB ...
    sweep_number                              int32 4B ...
    sweep_fixed_angle                         float32 4B ...
    sweep_mode                                <U188 752B ...
    nyquist_velocity                          (azimuth) float64 9kB ...

or the full volume!

dt = xd.io.open_cfradial1_datatree(file)
dt
<xarray.DatasetView> Size: 1kB
Dimensions:              (sweep: 1)
Dimensions without coordinates: sweep
Data variables:
    sweep_group_name     (sweep) <U7 28B 'sweep_0'
    sweep_fixed_angle    (sweep) float32 4B ...
    latitude             float64 8B ...
    longitude            float64 8B ...
    altitude             float64 8B ...
    time_coverage_start  |S192 192B ...
    time_coverage_end    |S192 192B ...
    volume_number        int32 4B ...
    platform_type        |S192 192B ...
    instrument_type      |S192 192B ...
    primary_axis         |S192 192B ...
Attributes:
    Conventions:  CF/Radial instrument_parameters ARM-1.3
    comment:      This is highly experimental and initial data. There are man...
    references:   See XSAPR Instrument Handbook
    source:       Atmospheric Radiation Measurement (ARM) program X-band Scan...
    institution:  U.S. Department of Energy Atmospheric Radiation Measurement...
    history:      created by jrobrien on cirrus127.ccs.ornl.gov at 2022-09-26...

Remove duplicate rays - this will help later!

dt["sweep_0"] = xd.util.remove_duplicate_rays(dt["sweep_0"])

Create a quick plot of the data

dt = dt.xradar.georeference()
dt["sweep_0"]
<xarray.DatasetView> Size: 202MB
Dimensions:                                   (azimuth: 1147, range: 668)
Coordinates:
    time                                      (azimuth) datetime64[ns] 9kB 20...
  * range                                     (range) float32 3kB 306.9 ... 4...
    elevation                                 (azimuth) float32 5kB 5.988 ......
  * azimuth                                   (azimuth) float32 5kB 0.05238 ....
    latitude                                  float64 8B 38.9
    longitude                                 float64 8B -106.9
    altitude                                  float64 8B 3.149e+03
    crs_wkt                                   int64 8B 0
    x                                         (azimuth, range) float32 3MB 0....
    y                                         (azimuth, range) float32 3MB 30...
    z                                         (azimuth, range) float32 3MB 3....
Data variables: (12/37)
    DBZ                                       (azimuth, range) float64 6MB ...
    VEL                                       (azimuth, range) float64 6MB ...
    WIDTH                                     (azimuth, range) float64 6MB ...
    ZDR                                       (azimuth, range) float64 6MB ...
    PHIDP                                     (azimuth, range) float64 6MB ...
    RHOHV                                     (azimuth, range) float64 6MB ...
    ...                                        ...
    snow_rate_m2009_1                         (azimuth, range) float64 6MB ...
    snow_rate_m2009_2                         (azimuth, range) float64 6MB ...
    sweep_number                              int32 4B ...
    sweep_fixed_angle                         float32 4B ...
    sweep_mode                                <U188 752B 'azimuth_surveillanc...
    nyquist_velocity                          (azimuth) float64 9kB ...
dt["sweep_0"]["corrected_reflectivity"].plot(x="x",
                                             y="y",
                                             cmap="ChaseSpectral",
                                             vmin=-10,
                                             vmax=30)
<matplotlib.collections.QuadMesh at 0x7f1d4c266320>
../_images/8ca95444114edc294cdb99c5d7c7dbc5c32ee73149e3f96c67fba24421690288.png

Plot along an azimuth with the power of xarray

DBZH = dt["sweep_0"]["corrected_reflectivity"]

# Select the northwest azimuth (315 degrees) to view reflectivity
DBZH.sel(azimuth=315., method='nearest').plot()
[<matplotlib.lines.Line2D at 0x7f1d4c19ef80>]
../_images/79ab505d87079aa472d96dd4e1d996da9a77eaa1bedfbe9b5ab1b6196472c708.png

The power of common data models

Using wradlib - Z(S) estimating snowfall!

See the discussion here for a more thorough literature review of the different relationships, but we can relate the properties of the scatterers to snowfall rates, using a log relationship:

Z = liquid_equivalent_snowfall * A * (S ^ B)

wradlib has a helper accessor to calculate this for this, solving for the snowfall rate in mm/hr, https://docs.wradlib.org/en/stable/zr.html

Here, we use values suitable for the Intermountain West, as this radar is in the Colorado Rockies.

a = 40
b = 2
snowfall = DBZH.wrl.zr.z_to_r(a=a, b=b)

# Update the attributes
snowfall.attrs["standard_name"]  = "snowfall_rate"
snowfall.attrs["long_name"] = "snwofall_rate"
/home/runner/miniconda3/envs/open-radar-pangeo-showcase-2024-dev/lib/python3.10/site-packages/wradlib/zr.py:62: RuntimeWarning: invalid value encountered in sqrt
  return (z / a) ** (1.0 / b)
snowfall.plot(x="x",
              y="y",
              cmap="ChaseSpectral",
              vmin=0,
              vmax=1)
<matplotlib.collections.QuadMesh at 0x7f1d4c018b20>
../_images/09853c0b98ff0e0c35fb2c5f59d44e37a680dbae2a5f1104724ce42db328e6be.png

Add this field back into our datatree!

dt["sweep_0"]["snowfall_rate"] = snowfall

Use Py-ART to grid this up!

radar = pyart.xradar.Xradar(dt)
radar
<xarray.DatasetView> Size: 1kB
Dimensions:              (sweep: 1)
Dimensions without coordinates: sweep
Data variables:
    sweep_group_name     (sweep) <U7 28B 'sweep_0'
    sweep_fixed_angle    (sweep) float32 4B ...
    latitude             float64 8B 38.9
    longitude            float64 8B -106.9
    altitude             float64 8B 3.149e+03
    time_coverage_start  |S192 192B ...
    time_coverage_end    |S192 192B ...
    volume_number        int32 4B ...
    platform_type        |S192 192B ...
    instrument_type      |S192 192B ...
    primary_axis         |S192 192B ...
Attributes:
    Conventions:  CF/Radial instrument_parameters ARM-1.3
    comment:      This is highly experimental and initial data. There are man...
    references:   See XSAPR Instrument Handbook
    source:       Atmospheric Radiation Measurement (ARM) program X-band Scan...
    institution:  U.S. Department of Energy Atmospheric Radiation Measurement...
    history:      created by jrobrien on cirrus127.ccs.ornl.gov at 2022-09-26...
grid = pyart.map.grid_from_radars(
    [radar],
    grid_shape=(21, 161, 161),
    grid_limits=(
        (
            0.0,
            5_000,
        ),
        (-20_000., 20_000.),
        (-20_000, 20_000.),
    ),
)
ds = grid.to_xarray()
ds.snowfall_rate.isel(z=1).plot(x='lon', y='lat')
<matplotlib.collections.QuadMesh at 0x7f1d4c22a8f0>
../_images/93cad4f4e3425db923a56d14e9776503371e18ec667be5612f030c5a1c5815a1.png

Danger

Not every method has been implemented for the xradar-radar object bridge. If you find an issue, open an issue!

Visualization fun

Let’s use some holoviz tools!

Create an Interactive PPI Plot

proj_crs = xd.georeference.get_crs(dt["sweep_0"].ds)
cart_crs = ccrs.Projection(proj_crs)
ref_plot = dt["sweep_0"]["corrected_reflectivity"].hvplot.quadmesh(x="x",
                                                        y="y",
                                                        cmap="ChaseSpectral",
                                                        rasterize=True,
                                                        height=500,
                                                        width=600,
                                                        title = "Refletivity (dBz)",
                                                        clim=(-10, 30))
ref_plot
snow_plot = dt["sweep_0"]["snowfall_rate"].hvplot.quadmesh(x="x",
                                                            y="y",
                                                            cmap="ChaseSpectral",
                                                            rasterize=True,
                                                            height=500,
                                                            width=600,
                                                            title = "Snowfall rate (mm/hr)",
                                                            clim=(0, 1))
snow_plot
(snow_plot + ref_plot).cols(1)

Summary

Within this notebook, we looked at the current methods of working with radar data in Python - using Py-ART and xradar!

What’s next?

Stay tuned - following along with the:

Resources and references